package framework.view.components.button
{
import framework.core.FontLib;

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BitmapFilterQuality;
import flash.filters.GlowFilter;
import flash.text.AntiAliasType;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.utils.getDefinitionByName;

import framework.core.UIWidget;
import framework.view.components.text.IText;

import framework.utils.TextUtil;

public class CommonButton extends Sprite implements IText
{
	//==========================================================================
	//  Class constants
	//==========================================================================
	protected static const STATE_UP:String = "up";
	protected static const STATE_OUT:String = "out";
	protected static const STATE_DOWN:String = "down";
	
	protected static const STATE_DISABLE:String = "disable";
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function CommonButton()
	{
		init();
	}
	//==========================================================================
	//  Variables
	//==========================================================================
	protected var outSkin:DisplayObject;
	protected var overSkin:DisplayObject;
	protected var downSkin:DisplayObject;
	
	protected var disableSkin:DisplayObject;
	
	protected var skinContainer:Sprite;
	protected var labelTF:TextField;
	protected var _id:int;
	
	public function get textField():TextField
	{
		return labelTF;
	}
	
	protected var format:TextFormat;
	//==========================================================================
	//  Properties
	//==========================================================================
	public function set outSkinRef(value:String):void
	{
		var classRef:Class = UIWidget.getClassReference(value) as Class;	
		outSkin = new classRef() as DisplayObject;
		
		changeSkin(outSkin, STATE_OUT);
	}
	
	public function set overSkinRef(value:String):void
	{
		var classRef:Class = UIWidget.getClassReference(value) as Class;	
		overSkin = new classRef() as DisplayObject;
	}
	
	public function set downSkinRef(value:String):void
	{
		var classRef:Class = UIWidget.getClassReference(value) as Class;	
		downSkin = new classRef() as DisplayObject;
	}
	
	public function set disableSkinRef(value:String):void
	{
		var classRef:Class = UIWidget.getClassReference(value) as Class;   
		disableSkin = new classRef() as DisplayObject;
	}
	
	protected var buttonWidth:Number = 62;
	
	override public function set width(value:Number) : void
	{
		buttonWidth = value;
		if (skinContainer.numChildren > 0)
		{
			skinContainer.getChildAt(0).width = buttonWidth;
			updateTextFormat();
		}
	}
	
	override public function get width() : Number
	{
		return buttonWidth;
	}
	
	protected var buttonHeight:Number = 15;
	
	override public function set height(value:Number) : void
	{
		buttonHeight = value;
		if (skinContainer.numChildren > 0)
		{
			skinContainer.getChildAt(0).height = buttonHeight;
			updateTextFormat();
		}
	}
	
	override public function get height() : Number
	{
		return buttonHeight;
	}
	
	public function set autoSize(value:String):void
	{
		labelTF.autoSize = value;
		updateTextFormat();
	}
    
    public function get autoSize():String
    {
        return labelTF.autoSize;
    }
	
	public function set fontName(value:String):void
	{
		format.font = value;
		updateTextFormat();
	}
    
    public function get fontName():String
    {
        return format.font;
    }
	
	public function set fontSize(value:Object):void
	{
		format.size = value;
		updateTextFormat();
	}
    
    public function get fontSize():Object
    {
        return format.size;
    }
	
	public function set bold(value:Boolean):void
	{
		format.bold = value;
		updateTextFormat();
	}
    
    public function get bold():Boolean
    {
        return format.bold;
    }
	
	public function set text(value:String):void
	{
		labelTF.text = value;
		labelTF.width = labelTF.textWidth + 4;
		updateTextFormat();
	}
    
    public function get text():String
    {
        return labelTF.text;
    }
	
	public function set htmlText(value:String):void
	{
		labelTF.htmlText = value;
		labelTF.width = labelTF.textWidth + 4;
		updateTextFormat();
	}
    
    public function get htmlText():String
    {
        return labelTF.htmlText;
    }
	
	public function set color(value:Object):void
	{
		
	}
    
    public function get color():Object
    {
        return 0;
    }
	
	private var overColor:uint = 0xF8FAFA;
	
	public function set rollOverColor(value:uint):void
	{
		overColor = value;
		updateTextFormat();
	}	
	
	public function get rollOverColor():uint
	{
		return overColor;
	}
	
	private var outColor:uint = 0xF8FAFA;
	
	public function set rollOutColor(value:uint):void
	{
		format.color = value;
		outColor = value;
		updateTextFormat();
	}	
    
    public function get rollOutColor():uint
    {
        return outColor;
    }
	
	private var downColor:uint = 0xF8FAFA;
	
	public function set mouseDownColor(value:uint):void
	{
		downColor = value;
		updateTextFormat();
	}
    
    public function get mouseDownColor():uint
    {
        return downColor;
    }
	
	private var disableColor:uint = 0xF8FAFA;
	
	public function set disableButtonColor(value:uint):void
	{
		disableColor = value;
		updateTextFormat();
	}
    
    public function get disableButtonColor():uint
    {
        return disableColor;
    }
	
	public function set leading(value:Object):void
	{
		format.leading = value;
		updateTextFormat();
	}
    
    public function get leading():Object
    {
        return format.leading;
    }
	
	public function set letterSpacing(value:Object):void
	{
		format.letterSpacing = value;
		updateTextFormat();
	}
    
    public function get letterSpacing():Object
    {
        return this.format.letterSpacing;
    }
    
    public function set embedFonts(value:Boolean):void
    {
        this.labelTF.embedFonts = value;
        updateTextFormat();
    }
    
    public function get embedFonts():Boolean
    {
        return this.labelTF.embedFonts;
    }
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function updateTextFormat():void
	{
		labelTF.defaultTextFormat = format;
		labelTF.setTextFormat(format);
		labelTF.height = labelTF.textHeight + 4;
		if (skinContainer.numChildren > 0)
		{			
			var skin:DisplayObject = skinContainer.getChildAt(0);
			labelTF.width = skin.width;
			labelTF.y = (buttonHeight - labelTF.height) / 2;
		}
		else
		{
			labelTF.width = labelTF.textWidth + 4;
		}
	}
	
	public function resize():void
	{
		
	}
	
	public function dispose(): void {
		removeButtonListeners();
		
		while (this.numChildren > 0)
		{
			this.removeChildAt(0);
		}
		outSkin = null;
		overSkin = null;
		downSkin = null;
		disableSkin = null;
		skinContainer = null;
		labelTF = null;
	}
	
    private var _enable:Boolean = true;
    
    public function get enable():Boolean
    {
        return _enable;
    }
	
	public function set enable(value:Boolean):void
	{
		if (value)
		{	
			changeSkin(outSkin, STATE_OUT);
			this.mouseEnabled = true;
			addButtonListeners();
		}
		else
		{
			removeButtonListeners();
			changeSkin(disableSkin, STATE_DISABLE);
			this.mouseEnabled = false;
		}
	}
	//==========================================================================
	//  Protected methods
	//==========================================================================
	protected function init():void
	{
		this.buttonMode = true;
		this.mouseChildren = false;
		
		skinContainer = new Sprite();
		addChild(skinContainer);
		
		labelTF = new TextField();
		labelTF.multiline = labelTF.wordWrap = false;
		labelTF.autoSize = TextFieldAutoSize.NONE;
        labelTF.embedFonts = true;
		labelTF.mouseWheelEnabled = false;
        labelTF.antiAliasType = AntiAliasType.ADVANCED;
		labelTF.selectable = false;
		addChild(labelTF);
        
        var glow:GlowFilter = new GlowFilter(0x1B1C1C, 1, 4, 4, 10, BitmapFilterQuality.LOW);//024D7B
        labelTF.filters = [ glow ];
		
		format = labelTF.getTextFormat();
        format.size = 15;
        format.font = FontLib.UI_FONT_NAME;
		format.align = TextFormatAlign.CENTER;
		labelTF.defaultTextFormat = format;
		
		addButtonListeners();		
	}
	
	public function addButtonListeners(e: Event = null): void {
		this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false, 0, true);
		this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler, false, 0, true);
		this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
		this.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
	}
	
	public function removeButtonListeners():void
	{
		this.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false);
		this.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler, false);
		this.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false);
		this.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false);
	}
	
	public function get id():int
	{
		return _id;
	}
	
	public function set id(value:int):void
	{
		_id = value;
	}
	
	protected function changeSkin(skin:DisplayObject, state:String):void
	{
		//Maybe the dispose() method was already executed
		if (!skinContainer) return;
		
		if (skinContainer.numChildren > 0)
		{
			skinContainer.removeChild(skinContainer.getChildAt(0));
		}
		skin.width = buttonWidth;
		skin.height = buttonHeight;
		skinContainer.addChild(skin);
		switch (state)
		{
			case STATE_UP:
				format.color = overColor;
				break;
			case STATE_OUT:
				format.color = outColor;
				break;
			case STATE_DOWN:
				format.color = downColor;
				break;
			case STATE_DISABLE:
				format.color = disableColor;
				break;
		}
		updateTextFormat();
		
	}
	
	//==========================================================================
	//  Event handlers
	//==========================================================================
	protected function rollOverHandler(event:MouseEvent):void
	{
		changeSkin(overSkin, STATE_UP);
	}
	
	protected function rollOutHandler(event:MouseEvent):void
	{
		changeSkin(outSkin, STATE_OUT);
	}
	
	protected function mouseDownHandler(event:MouseEvent):void
	{
		changeSkin(downSkin, STATE_DOWN);
	}
	
	protected function mouseUpHandler(event:MouseEvent):void
	{
		changeSkin(overSkin, STATE_UP);
	}
	
	public function textFieldResize():void
	{
		TextUtil.setFixRectText(this.textField, this.textField.text, fontName);
		format = textField.getTextFormat();
		updateTextFormat();
	}
}
}

